package fun.anin.aninhongbao.sender;

import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageDeliveryMode;
import org.springframework.amqp.core.MessagePostProcessor;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.UUID;

/***
 * RabbitMQ
 * @author anin
 * @date: 2020/4/2 14:51
 * @version : V1.0
 */
@Slf4j
@Component
public class RabbitMQUtil {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    /**
     * 异步发送
     * @param name      队列
     */
    public void send(String name,Object message){
        rabbitTemplate.convertAndSend(name, message);
    }

    /**
     * 异步发送
     * @param exchange      交换机
     * @param routingKey    队列
     * @param message       消息
     */
    public void send(String exchange,String routingKey,Object message){
        rabbitTemplate.convertAndSend(exchange,routingKey, message);
    }

    /**
     * 延迟发送红包退还消息
     * @param exchange      交换机
     * @param routingKey    队列
     * @param message       消息
     */
    public void sendLazy(String exchange,String routingKey,int backTime,Object message){
        rabbitTemplate.setMandatory(true);
        rabbitTemplate.setConfirmCallback(confirmCallback);
        rabbitTemplate.setReturnCallback(returnCallback);
        //id + 时间戳 全局唯一
        CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());

        //发送消息时指定 header 延迟时间
        rabbitTemplate.convertAndSend(exchange,routingKey, message,
                new MessagePostProcessor() {
                    @Override
                    public Message postProcessMessage(Message message) throws AmqpException {
                        //设置消息持久化
                        message.getMessageProperties().setDeliveryMode(MessageDeliveryMode.PERSISTENT);
                        message.getMessageProperties().setDelay(backTime);
                        return message;
                    }
                }, correlationData);
    }

    final RabbitTemplate.ConfirmCallback confirmCallback= new RabbitTemplate.ConfirmCallback() {
        public void confirm(CorrelationData correlationData, boolean ack, String cause) {
//            if (ack) {
//                log.info("message send success! messageId:{} returnMessage:{} cause:{}",correlationData.getId(),correlationData.getReturnedMessage(),cause);
//            } else {
//                log.info("message send error! messageId:{} returnMessage:{} cause:{}",correlationData.getId(),correlationData.getReturnedMessage(),cause);
//            }
        }
    };

    final RabbitTemplate.ReturnCallback returnCallback = new RabbitTemplate.ReturnCallback() {
        public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
            System.out.println("return exchange: " + exchange + ", routingKey: "
                    + routingKey + ", replyCode: " + replyCode + ", replyText: " + replyText);
        }
    };
}
